
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package receiver;
import common.Checksum;
import common.Packet;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author Dunekacke
 */
public class Alternating
{
    final public int PORT = 12723;
    public ArrayList<Packet> packetArray = new ArrayList();
    public int last_packet = 1;
    DatagramSocket serverSocket;
    public Alternating()
    {
  
    }
    public void run()
    {
        fooBar();
    }
    private void fooBar()
    {
    System.out.println("Server Started");
        try {
             serverSocket = new DatagramSocket(12723);
            byte[] receiveData = new byte[512];
            int i = 0;
            boolean allPacketsReceived = false;
            do
            {
                //System.out.println("waiting for packet " + i);
                DatagramPacket incomingPacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(incomingPacket);
                Packet receivedPacket = new Packet(incomingPacket.getData());
                InetAddress IPAddress = incomingPacket.getAddress();
                int port = incomingPacket.getPort();

                if (receivedPacket.checksum != Checksum.calculate(receivedPacket))
                {
                    // Packet was corrupt: return sequence of previous packet
					System.out.println(receivedPacket.checksum);
                    acknowledge(serverSocket, last_packet, IPAddress, port);
                }
                else if (receivedPacket.sequence != last_packet)
                {
                    // Packet is the next packet in the sequence: store it
                    last_packet = receivedPacket.sequence;
                    acknowledge(serverSocket, last_packet, IPAddress, port);
                    packetArray.add(receivedPacket);
                    i++;
                }
                else
                {
                    // Packet should be acknowledged but not stored
                    acknowledge(serverSocket, last_packet, IPAddress, port);
                }
                allPacketsReceived = receivedPacket.flag == Packet.END_FLAG;
            } while (!allPacketsReceived);
            
            // Last packet was not part of the file: remove it before creating
            packetArray.remove(packetArray.size() - 1);
            makeFile();
            serverSocket.close();
        } catch (SocketException e) {
                e.printStackTrace();
        } catch (IOException e) {
                e.printStackTrace();
        }
    }
    
    private void acknowledge(DatagramSocket serverSocket, int lastPacket, InetAddress IPAddress, int port)
    {
        byte[] content = "ACK".getBytes();
        Packet packet = new Packet(content,(byte)lastPacket, Packet.NACK_FLAG );
        DatagramPacket sendPacket = 
                new DatagramPacket(
                packet.getRaw(), packet.getRaw().length,
                IPAddress, port);
        try {
            serverSocket.send(sendPacket);
        } catch (IOException ex) {
            Logger.getLogger(Alternating.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void makeFile() throws IOException
    {
        String filename = new String(packetArray.get(0).content);
        System.out.println(filename);
        try {
            FileOutputStream out = new FileOutputStream(filename,false);
            for(int i = 1 ; i < packetArray.size(); i++)
            {
                out.write(packetArray.get(i).content);
            }
            out.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Alternating.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException e) {
            
        }
    }
    
}

